//
//  PPAlbumManager.m
//  pickpic
//
//  Created by Jinxiao on 9/5/16.
//  Copyright © 2016 MicroDream. All rights reserved.
//

#import "PPAlbumManager.h"

#import "PPAlbumModel.h"
#import "PPAlbumCustomTagModel.h"

#import "PPImageTransaction.h"
#import "PPAlbumFetcher.h"

#import "PPHomeEbookModel.h"
@interface PPAlbumManager ()

@end

@implementation PPAlbumManager

+ (instancetype)sharedInstance {
    static id instance;
    static dispatch_once_t once;
    dispatch_once(&once, ^{
        instance = self.new;
    });

    return instance;
}

- (void)clean {
    [PPAlbumModel deleteAll];
    [PPAlbumImageModel deleteAll];
    [PPAlbumTagModel deleteAll];

    [[NSManagedObjectContext threadObjectContext] saveContext];
}

- (void)synchronize {

    dispatch_group_t group = dispatch_group_create();

    NSArray <PPAlbumModel *> *albums = [PPAlbumModel all];
    [albums enumerateObjectsUsingBlock:^(PPAlbumModel *_Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) {

        dispatch_group_enter(group);
        [self commitOfflineAlbumWithAlbumUUID:obj.auuid completion:^{
            dispatch_group_leave(group);
        }];

    }];

    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        [self synchronizeRemoteAlbumsWithCompletion:nil];
    });
}

#pragma mark - OFFLINE

- (void)offlineCreateAlbumWithArtworks:(NSArray<PPAbstractArtwork *> *)artworks tags:(NSArray<PPAlbumTagElement *> *)tags title:(NSString *)title description:(NSString *)description order:(NSNumber *)order permission:(NSNumber *)permission privacy:(NSNumber *)privacy privacyUserIDs:(NSArray<NSString *> *)privacyUserIDs coverUUID:(NSString *)coverUUID {

    NSString *auuid = [NSString uuid];

    PPAlbumModel *album = [PPAlbumModel existingAlbumForUUID:auuid];

    if(tags.count > 0) {
        for(PPAlbumTagElement *element in tags) {
            PPAlbumTagModel *tag = [PPAlbumTagModel create];
            tag.tagID = element.tagID;
            tag.name = element.name;
            tag.auuid = auuid;
            tag.isHot = @(element.isHot);
        }
    }

    dispatch_group_t group = dispatch_group_create();

    for(PPAbstractArtwork *artwork in artworks) {

        PPAlbumImageModel *image = [PPAlbumImageModel existingAlbumImageForUUID:artwork.uuid];
        image.auuid = auuid;

        if(artwork.desc.length > 0) {
            image.desc = artwork.desc;
            image.modified = @(YES);
        }

        if([image.uuid isEqualToString:coverUUID]) {
            image.isCover = @(YES);
        } else {
            image.isCover = @(NO);
        }

        image.created = @(YES);

        dispatch_group_enter(group);
        [[PPImageTransaction sharedInstance] prepareTransactionWithArtwork:artwork completion:^{
            dispatch_group_leave(group);
        }];
    }

    // 更新album
    if(title != nil) {
        album.title = title;
    }

    if(description != nil) {
        album.desc = description;
    }

    if(privacy != nil) {
        album.privacy = privacy;
    }

    if(privacyUserIDs != nil && privacyUserIDs.count > 0) {
        album.privacyUserIDs = [privacyUserIDs componentsJoinedByString:@","];
    }

    if(permission != nil) {
        album.permission = permission;
    }

    if(order != nil) {
        album.order = order;
    }

    album.publish = @([NSDate date].timeIntervalSince1970);
    album.update = @([NSDate date].timeIntervalSince1970);
    album.created = @(YES);
    album.modified = @(YES);

    [[NSManagedObjectContext threadObjectContext] saveContext];

    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        [self commitOfflineCreatedAlbumWithAlbumUUID:auuid completion:nil];

        [[NSNotificationCenter defaultCenter] postNotificationName:PPAlbumManagerDidChangeLocalAlbumsNotification object:nil];
    });
}

- (void)offlineModifyAlbumWithAlbumUUID:(NSString *)auuid insertedArtworks:(NSArray <PPAbstractArtwork *> *)insertedArtworks modifiedArtworks:(NSArray <PPAbstractArtwork *> *)modifiedArtworks deletedArtworks:(NSArray <PPAbstractArtwork *> *)deletedArtworks tags:(NSArray <PPAlbumTagElement *> *)tags title:(NSString *)title description:(NSString *)description order:(NSNumber *)order permission:(NSNumber *)permission privacy:(NSNumber *)privacy privacyUserIDs:(NSArray <NSString *> *)privacyUserIDs coverUUID:(NSString *)coverUUID {

    if(auuid == nil) {
        return;
    }

    PPAlbumModel *album = [PPAlbumModel existingAlbumForUUID:auuid];

    BOOL modified = NO;

    // 更新album
    if(title != nil && !equal(title, album.title)) {
        album.title = title;
        modified = YES;
    }

    if(description != nil && !equal(description, album.desc)) {
        album.desc = description;
        modified = YES;
    }

    if(privacy != nil && !equal(privacy, album.privacy)) {
        album.privacy = privacy;
        modified = YES;
    }

    NSMutableSet <NSString *> *albumPrivacyuserIDs = [NSMutableSet set];

    if(album.privacyUserIDs.length > 0) {
        [albumPrivacyuserIDs addObjectsFromArray:[album.privacyUserIDs componentsSeparatedByString:@","]];
    }

    NSMutableSet <NSString *> *newPrivacyuserIDs = [NSMutableSet set];

    if(albumPrivacyuserIDs.count > 0) {
        [newPrivacyuserIDs addObjectsFromArray:privacyUserIDs];
    }

    if(![newPrivacyuserIDs isEqualToSet:albumPrivacyuserIDs]) {
        album.privacyUserIDs = [privacyUserIDs componentsJoinedByString:@","];
        modified = YES;
    }

    if(permission != nil && !equal(permission, album.permission)) {
        album.permission = permission;
        modified = YES;
    }

    if(order != nil && !equal(order, album.order)) {
        album.order = order;
        modified = YES;
    }

    // MARK: 更新tags
    if(tags != nil) {
        NSArray *albumTags = [PPAlbumTagModel where:@{@"auuid" : auuid}];

        NSMutableArray *deletedTags = [NSMutableArray array];

        for(PPAlbumTagModel *tag in albumTags) {

            BOOL exists = NO;

            for(PPAlbumTagElement *element in tags) {
                if([element.name isEqualToString:tag.name]) {
                    exists = YES;
                    break;
                }
            }

            if(!exists) {
                [deletedTags addObject:tag];

                modified = YES;
            }
        }

        [deletedTags makeObjectsPerformSelector:@selector(delete)];

        NSMutableArray *insertedTags = [NSMutableArray array];

        for(PPAlbumTagElement *element in tags) {

            BOOL exists = NO;

            for(PPAlbumTagModel *tag in albumTags) {
                if([tag.name isEqualToString:element.name]) {
                    exists = YES;
                    break;
                }
            }

            if(!exists) {
                PPAlbumTagModel *tag = [PPAlbumTagModel create];
                tag.tagID = element.tagID;
                tag.name = element.name;
                tag.auuid = auuid;
                tag.isHot = @(element.isHot);

                [insertedTags addObject:tag];

                modified = YES;
            }
        }
    }

    dispatch_group_t group = dispatch_group_create();

    for(PPAbstractArtwork *artwork in insertedArtworks) {
        PPAlbumImageModel *image = [PPAlbumImageModel existingAlbumImageForUUID:artwork.uuid];
        image.auuid = auuid;

        if(artwork.desc.length > 0) {
            image.desc = artwork.desc;
            image.modified = @(YES);
        }

        if([image.uuid isEqualToString:coverUUID]) {
            image.isCover = @(YES);
        } else {
            image.isCover = @(NO);
        }

        image.created = @(YES);

        dispatch_group_enter(group);
        [[PPImageTransaction sharedInstance] prepareTransactionWithArtwork:artwork completion:^{
            dispatch_group_leave(group);
        }];
    }

    if(modifiedArtworks != nil) {
        for(PPAbstractArtwork *artwork in modifiedArtworks) {
            PPAlbumImageModel *image = [PPAlbumImageModel existingAlbumImageForUUID:artwork.uuid];
            image.desc = artwork.desc;
            image.modified = @(YES);
        }
    }

    NSString *deletedCoverUUID = nil;

    if(deletedArtworks != nil) {
        for(NSInteger index = 0; index < deletedArtworks.count; index++) {
            PPAbstractArtwork *artwork = deletedArtworks[index];

            PPAlbumImageModel *image = [PPAlbumImageModel existingAlbumImageForUUID:artwork.uuid];
            image.deleted = @(YES);

            [[PPImageTransaction sharedInstance] endTransactionWithItendifier:artwork.transactionIdentifier];

            if([image.key isEqualToString:album.coverKey] || image.isCover.boolValue) {
                deletedCoverUUID = image.uuid;
            }
        }

        [[NSManagedObjectContext threadObjectContext] saveContext];
    }

    // 更新封面
    if((coverUUID == nil && deletedCoverUUID != nil) || ([coverUUID isEqualToString:deletedCoverUUID])) {
        NSArray <PPAlbumImageModel *> *images = [PPAlbumImageModel where:@{@"auuid" : auuid, @"deleted" : @(NO)}];

        NSArray <PPAlbumImageModel *> *sortedImages = nil;

        if(album.order.integerValue == PPAlbumOrderAsc) {
            sortedImages = images;
        } else {
            sortedImages = [images.reverseObjectEnumerator allObjects];
        }

        coverUUID = sortedImages.firstObject.uuid;
    }

    if(coverUUID != nil) {
        NSArray <PPAlbumImageModel *> *images = [PPAlbumImageModel where:@{@"auuid" : auuid, @"deleted" : @(NO)}];

        [images enumerateObjectsUsingBlock:^(PPAlbumImageModel *_Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) {
            if([obj.uuid isEqualToString:coverUUID]) {
                if(obj.host.length > 0 && obj.key.length > 0) {
                    album.coverHost = obj.host;
                    album.coverKey = obj.key;
                    album.modified = @(YES);
                } else {
                    obj.isCover = @(YES);
                }
            } else {
                obj.isCover = @(NO);
            }
        }];

        [[NSManagedObjectContext threadObjectContext] saveContext];
    }

    if(modified) {
        album.modified = @(modified);
    }

    if(insertedArtworks.count > 0) {
        album.update = @([NSDate date].timeIntervalSince1970);
    }

    [[NSManagedObjectContext threadObjectContext] saveContext];

    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        [self commitOfflineAlbumWithAlbumUUID:auuid completion:nil];

        [[NSNotificationCenter defaultCenter] postNotificationName:PPAlbumManagerDidChangeLocalAlbumsNotification object:nil];
    });
}

- (void)offlineDeleteAlbumWithAlbumUUID:(NSString *)auuid {

    if(auuid == nil) {
        return;
    }

    PPAlbumModel *album = [PPAlbumModel find:@{@"auuid" : auuid}];

    album.deleted = @(YES);

    for(PPAlbumImageModel *image in [PPAlbumImageModel where:@{@"auuid" : auuid}]) {
        [[PPImageTransaction sharedInstance] endTransactionWithItendifier:image.artwork.transactionIdentifier];

        [image delete];
    }

    for(PPAlbumTagModel *tag in [PPAlbumTagModel where:@{@"auuid" : auuid}]) {
        [tag delete];
    }

    [[NSManagedObjectContext threadObjectContext] saveContext];

    [[NSNotificationCenter defaultCenter] postNotificationName:PPAlbumManagerDidChangeLocalAlbumsNotification object:nil];

    [self commitOfflineDeletedAlbumWithAlbumUUID:auuid completion:nil];
}

#pragma mark - COMMIT

- (void)commitOfflineCreatedAlbumWithAlbumUUID:(NSString *)auuid completion:(void (^)(void))completion {
    if(auuid == nil) {
        !completion ? : completion();

        return;
    }

    PPAlbumModel *album = [PPAlbumModel find:@{@"auuid" : auuid}];

    if(album == nil) {
        !completion ? : completion();

        return;
    }

    __block NSError *error_ = nil;

    NSMutableArray *pictures = [NSMutableArray array];
    NSMutableDictionary *uuidMap = [NSMutableDictionary dictionary];

    NSArray <PPAlbumImageModel *> *images = [PPAlbumImageModel where:@{@"auuid" : auuid}];

    [images enumerateObjectsUsingBlock:^(PPAlbumImageModel *_Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) {
        if(obj.URLString == nil) {
            [pictures addSafeObject:obj.artwork.transactionIdentifier];
            [uuidMap setSafeObject:obj.uuid forKey:obj.artwork.transactionIdentifier];
        }
    }];


    NSMutableArray *newTagNames = [NSMutableArray array];
    NSMutableDictionary *newTagNamesMap = [NSMutableDictionary dictionary];

    NSArray <PPAlbumTagModel *> *tags = [PPAlbumTagModel where:@{@"auuid" : auuid}];
    [tags enumerateObjectsUsingBlock:^(PPAlbumTagModel *_Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) {
        if(obj.tagID.integerValue == 0) {
            [newTagNames addSafeObject:obj.name];
            [newTagNamesMap setSafeObject:obj.objectID forKey:obj.name];
        }
    }];

    dispatch_group_t group = dispatch_group_create();

    if(newTagNames.count > 0) {
        dispatch_group_enter(group);

        [PPNetworkService createTagWithNames:newTagNames callback:^(id data, NSError *error) {
            if(error != nil) {
                error_ = error;
            } else {
                NSManagedObjectContext *context = [NSManagedObjectContext threadObjectContext];

                [newTagNamesMap enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL *_Nonnull stop) {
                    PPAlbumTagModel *tag = [context objectWithID:obj];

                    for(NSDictionary *result in [data validArrayForKey:@"tags"]) {
                        NSString *name = [result validStringForKey:@"name"];

                        if([name isEqualToString:tag.name]) {
                            tag.tagID = [result validNumberForKey:@"tagid"];
                            tag.pinyin = [result validStringForKey:@"pinyin"];
                            tag.index = [result validNumberForKey:@"index"];

                            PPAlbumCustomTagModel *customTag = [PPAlbumCustomTagModel existingAlbumCustomTagForTagID:tag.tagID];
                            customTag.name = tag.name;

                            break;
                        }
                    }
                }];

                [context saveContext];
            }

            dispatch_group_leave(group);
        }];
    }

    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        if(error_ != nil) {
            !completion ? : completion();

            return;
        }

        NSMutableArray *tagIDs = [NSMutableArray array];
        NSMutableArray *hotTagIDs = [NSMutableArray array];
        NSArray <PPAlbumTagModel *> *tags = [PPAlbumTagModel where:@{@"auuid" : auuid}];
        [tags enumerateObjectsUsingBlock:^(PPAlbumTagModel *_Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) {
            if(obj.isHot.boolValue) {
                [hotTagIDs addSafeObject:obj.tagID];
            } else {
                [tagIDs addSafeObject:obj.tagID];
            }
        }];

        NSArray *privacyUserIDs = [album.privacyUserIDs componentsSeparatedByString:@","];

        [PPNetworkService createAlbumWithTitle:album.title desc:album.desc privacy:album.privacy privacySettings:privacyUserIDs commentSetting:album.permission tags:tagIDs hotTags:hotTagIDs pictures:pictures order:album.order callback:^(id data, NSError *error) {
            [self didCreateAlbumWithAlbumUUID:auuid results:data error:error uuidMap:uuidMap completion:^{
                !completion ? : completion();
            }];
        }];
    });
}

- (void)commitOfflineDeletedAlbumWithAlbumUUID:(NSString *)auuid completion:(void (^)(void))completion {

    if(auuid == nil) {
        !completion ? : completion();

        return;
    }

    PPAlbumModel *album = [PPAlbumModel find:@{@"auuid" : auuid}];

    if(album == nil || album.created.boolValue) {
        !completion ? : completion();

        return;
    }

    [PPNetworkService deleteAlbumWithAlbumID:album.albumID callback:^(id data, NSError *error) {
        if(error == nil) {
            PPAlbumModel *album = [PPAlbumModel find:@{@"auuid" : auuid}];

            [album delete];

            [[NSManagedObjectContext threadObjectContext] saveContext];
        } else {

        }

        !completion ? : completion();
    }];

}

- (void)commitOfflineModifiedAlbumWithAlbumUUID:(NSString *)auuid completion:(void (^)(void))completion {

    if(auuid == nil) {
        !completion ? : completion();

        return;
    }

    PPAlbumModel *album = [PPAlbumModel find:@{@"auuid" : auuid}];

    NSNumber *albumID = album.albumID;

    if(album == nil) {
        !completion ? : completion();

        return;
    }

    __block NSError *error_ = nil;


    dispatch_group_t group = dispatch_group_create();


    // 同步TAG
    NSMutableArray *newTagNames = [NSMutableArray array];
    NSMutableDictionary *newTagNamesMap = [NSMutableDictionary dictionary];

    NSArray <PPAlbumTagModel *> *tags = [PPAlbumTagModel where:@{@"auuid" : auuid}];
    [tags enumerateObjectsUsingBlock:^(PPAlbumTagModel *_Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) {
        if(obj.tagID.integerValue == 0) {
            [newTagNames addSafeObject:obj.name];
            [newTagNamesMap setSafeObject:obj.objectID forKey:obj.name];
        }
    }];

    if(newTagNames.count > 0) {
        dispatch_group_enter(group);

        [PPNetworkService createTagWithNames:newTagNames callback:^(id data, NSError *error) {
            if(error != nil) {
                error_ = error;
            } else {
                NSManagedObjectContext *context = [NSManagedObjectContext threadObjectContext];

                [newTagNamesMap enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL *_Nonnull stop) {
                    PPAlbumTagModel *tag = [context objectWithID:obj];

                    for(NSDictionary *result in [data validArrayForKey:@"tags"]) {
                        NSString *name = [result validStringForKey:@"name"];

                        if([name isEqualToString:tag.name]) {
                            tag.tagID = [result validNumberForKey:@"tagid"];
                            tag.pinyin = [result validStringForKey:@"pinyin"];
                            tag.index = [result validNumberForKey:@"index"];

                            PPAlbumCustomTagModel *customTag = [PPAlbumCustomTagModel existingAlbumCustomTagForTagID:tag.tagID];
                            customTag.name = tag.name;

                            break;
                        }
                    }
                }];

                [context saveContext];
            }

            dispatch_group_leave(group);
        }];
    }

    // 同步PICTURE
    NSArray <PPAlbumImageModel *> *images = [PPAlbumImageModel where:@{@"auuid" : auuid}];

    NSMutableArray <PPAlbumImageModel *> *insertedPictures = [NSMutableArray array];
    NSMutableArray <PPAlbumImageModel *> *deletedPictures = [NSMutableArray array];
    NSMutableArray <PPAlbumImageModel *> *modifiedPictures = [NSMutableArray array];

    NSMutableDictionary *uuidMap = [NSMutableDictionary dictionary];

    for(PPAlbumImageModel *image in images) {
        if(image.deleted.boolValue) {
            [deletedPictures addSafeObject:image];
        } else if(image.created.boolValue) {
            [insertedPictures addSafeObject:image];
            [uuidMap setSafeObject:image.uuid forKey:image.artwork.transactionIdentifier];
        } else if(image.modified.boolValue) {
            [modifiedPictures addSafeObject:image];
        }
    }

    if(insertedPictures.count > 0) {
        NSMutableArray *pictures = [NSMutableArray array];
        [insertedPictures enumerateObjectsUsingBlock:^(PPAlbumImageModel *_Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) {
            if([[PPImageTransaction sharedInstance] containsIdentifier:obj.uuid]) {
                return;
            }

            [pictures addSafeObject:obj.artwork.transactionIdentifier];
        }];

        dispatch_group_enter(group);
        [PPNetworkService addPictureToAlbum:albumID pictures:pictures callback:^(id data, NSError *error) {
            [self didAddPicturesToAlbumWithAlbumID:albumID auuid:auuid results:data error:error uuidMap:uuidMap completion:^{
                dispatch_group_leave(group);
            }];
            
            PPLog(@"添加相片 %@",[data yy_modelToJSONString]);
            
            
        }];
    }

    if(modifiedPictures.count > 0) {
        [modifiedPictures enumerateObjectsUsingBlock:^(PPAlbumImageModel *_Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) {
            NSManagedObjectID *objectID = obj.objectID;

            dispatch_group_enter(group);
            [PPNetworkService updatePictureDescInAlbumID:albumID pictureID:obj.imageID pictureDesc:obj.desc callback:^(id data, NSError *error) {
                if(error == nil) {
                    PPAlbumImageModel *image = [[NSManagedObjectContext threadObjectContext] objectWithID:objectID];
                    image.modified = @(NO);
                    [image.managedObjectContext saveContext];
                }

                dispatch_group_leave(group);
            }];
        }];
    }

    if(deletedPictures.count > 0) {
        NSMutableArray *imageIDs = [NSMutableArray array];
        [deletedPictures enumerateObjectsUsingBlock:^(PPAlbumImageModel *_Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) {
            if(!obj.created.boolValue) {
                [imageIDs addSafeObject:obj.imageID];
            }
        }];

        dispatch_group_enter(group);
        [PPNetworkService deletePictureFromAlbum:albumID pictures:imageIDs callback:^(id data, NSError *error) {
            if(error == nil) {
                
                NSMutableArray *deletePictures = [NSMutableArray array];
                for(NSNumber *imageID in imageIDs) {
                    PPAlbumImageModel *image = [PPAlbumImageModel find:@{@"imageID" : imageID}];
                    
                    if(image == nil) {
                        continue;
                    }
                  
                    NSDictionary *deleteDic = @{
                                             @"pictureId":imageID,
                                             @"url":image.key,
                                             @"picType":@(2),
                                             @"operateType":@(2),
                                             };
                    [deletePictures addObject:deleteDic];
                    
                    
                    if ([album.coverKey isEqualToString:image.key]) {
                        NSDictionary *deleteCoverDic = @{
                                                 @"pictureId":imageID,
                                                 @"url":image.key,
                                                 @"picType":@(1),
                                                 @"operateType":@(2),
                                                 };
                        [deletePictures addObject:deleteCoverDic];
                    }
                    
                    
                    [image delete];
                }

                [[NSManagedObjectContext threadObjectContext] saveContext];
                
                [self queryAlbumEbookAlbumId:albumID order:album.order pictures:deletePictures updateCover:NO];
            }

//            [self updateAlbumeBookID:albumID cover:nil deletePictures:imageIDs addPictures:nil order:album.order];
            dispatch_group_leave(group);
        }];
    }

    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        if(error_ != nil) {
            !completion ? : completion();

            return;
        }

        NSMutableArray *tagIDs = [NSMutableArray array];
        NSMutableArray *hotTagIDs = [NSMutableArray array];
        NSArray <PPAlbumTagModel *> *tags = [PPAlbumTagModel where:@{@"auuid" : auuid}];
        [tags enumerateObjectsUsingBlock:^(PPAlbumTagModel *_Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) {
            if(obj.isHot.boolValue) {
                [hotTagIDs addSafeObject:obj.tagID];
            } else {
                [tagIDs addSafeObject:obj.tagID];
            }
        }];

        NSArray *privacyUserIDs = [album.privacyUserIDs componentsSeparatedByString:@","];

        PPAlbumModel *album = [PPAlbumModel find:@{@"auuid" : auuid}];
        NSArray <PPAlbumImageModel *> *images = [PPAlbumImageModel where:@{@"auuid" : auuid}];

        __block BOOL modified = NO;

        if(album.modified.boolValue) {
            modified = YES;
        } else {
            [images enumerateObjectsUsingBlock:^(PPAlbumImageModel *_Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) {
                if(obj.modified.boolValue) {
                    modified = YES;
                    *stop = YES;
                }
            }];
        }

        if(!modified) {
            !completion ? : completion();

            return;
        }

        [PPNetworkService updateAlbumWithAlbumID:album.albumID albumTitle:album.title albumDesc:album.desc privacy:album.privacy privacySettings:privacyUserIDs commentSetting:album.permission coverKey:album.coverKey coverHost:album.coverHost tags:tagIDs hotTags:hotTagIDs order:album.order callback:^(id data, NSError *error) {
            if(error == nil) {
                PPAlbumModel *album = [PPAlbumModel find:@{@"auuid" : auuid}];
                album.modified = @(NO);
                [album.managedObjectContext saveContext];
                
                
                PPHomeAlbumModel *homeAlbum = [self getAlbumInfo:album];
                NSNumber *picId = nil;
                for (PPPictureModel *pic in homeAlbum.pictures) {
                    
                    if ([pic.picKey isEqualToString:album.coverKey]) {
                        picId = pic.picID;
                    }
                }
                
                if ([picId integerValue] > 0) {
                    NSMutableArray *modifyArr = [NSMutableArray array];
                    NSDictionary *modifyDic = @{
                                                @"pictureId":picId,
                                                @"url":homeAlbum.coverKey,
                                                @"picType":@(1),
                                                @"operateType":@(3),
                                                };
                    [modifyArr addObject:modifyDic];
                    // 更新封面操作
                    [self queryAlbumEbookAlbumId:albumID order:album.order pictures:modifyArr updateCover:YES];
                }
            }

            [self commitOfflineAlbumWithAlbumUUID:auuid completion:completion];

//            [self updateAlbumeBookID:album.albumID cover:album.coverKey deletePictures:nil addPictures:nil order:album.order];
        }];
    });
}
/*
#pragma mark -更新电子书
- (void)updateAlbumeBookID:(NSNumber*)albumId cover:(NSString *)coverURL deletePictures:(NSArray *)deletePictures addPictures:(NSArray *)addPictures order:(NSNumber *)order{
    PPLog(@"更新电子书");
    //1.查询到所有图片信息
    //2.电子书
    NSDictionary *Dict = @{
                           @"pageInfo":@{@"page":@"1",@"rows":@"100"},
                           @"albumId":albumId,
                           };
    
    
//    "operateType":1,     //1,"增加";2,"删除";3,"修改";
//    "picType":1,    //图片类型:1,封面图；2,内页图,不为空
    [PPNetworkService queryAlbumPictureids:Dict callback:^(id data, NSError *error) {
        if (!error) {
            NSMutableArray *pics = [NSMutableArray array];
            if (deletePictures.count > 0) {
                for (NSNumber *number in deletePictures) {
                    PPLog(@"删除的有没有 %zd",[number integerValue]);
                }
            }
            
            for (NSDictionary *picDic in data[@"rows"]) {
                if (coverURL) {
                    if ([coverURL isEqualToString:picDic[@"url"]]) {
                        PPLog(@"电子书封面操作 = %@",coverURL);
                        NSDictionary *coverDic = @{
                                               @"pictureId":picDic[@"pictureId"],
                                               @"url":picDic[@"url"],
                                               @"picType":@(1),
                                               @"operateType":@(3),
                                               };
                         [pics addObject:coverDic];
                        
                    }
                    
                }else if (deletePictures.count >0){
                    for (NSNumber *picID in deletePictures) {
                        if ([picID compare:@([picDic[@"pictureId"] integerValue])] == NSOrderedSame) {
                             PPLog(@"电子书内页删除操作 = %@",picDic[@"url"]);
                            NSDictionary *dict = @{
                                                @"pictureId":picDic[@"pictureId"],
                                                   @"url":picDic[@"url"],
                                                   @"picType":@(2),
                                                   @"operateType":@(2),
                                                   };
                            [pics addObject:dict];
                            break;
                        }
                    }
                }else if (addPictures.count >0){
                    for (NSNumber *picID in addPictures) {
                        if ([picID compare:@([picDic[@"pictureId"] integerValue])] == NSOrderedSame) {
                             PPLog(@"电子书内页增加操作 = %@",picDic[@"url"]);
                            NSDictionary *dict = @{
                                                @"pictureId":picDic[@"pictureId"],
                                                   @"url":picDic[@"url"],
                                                   @"picType":@(2),
                                                @"operateType":@(1),
                                                   };
                            [pics addObject:dict];
                            break;
                        }
                    }
                    
                }else{return ;}
            }


            
            NSDictionary *row = @{@"page":@(1),@"rows":@(100)};
            
            NSDictionary *dict = @{@"albumId":albumId,
                                   @"pageInfo":row,
                                   @"order":[order integerValue]==1?@"desc":@"asc",
                                   };
            //查询是否有电子书
            [PPNetworkService gettemplateEbookListWithparams:dict callback:^(id data, NSError *error) {
            
                if ([data[@"total"] integerValue] > 0) {

                    //如果删除的是内页 判断内页是不是封面 是封面就要将其一并删除
                    if (deletePictures.count > 0 && data[@"common"]) {
                            PPHomeEbookModel *coverM = [PPHomeEbookModel yy_modelWithDictionary:data[@"common"]];
                            
                            
                        for (NSNumber *picID in deletePictures) {
                            if ([picID integerValue] ==[coverM.pictureId integerValue])  {
                                PPLog(@"是封面 = %zd",[coverM.pictureId integerValue]);
                            NSDictionary *coverDic = @{
                                                       @"pictureId":@([coverM.pictureId integerValue]),
                                                    @"url":coverM.url,
                                                    @"picType":@(1),
                                                       @"operateType":@(2),
                                                       };
                            
                            [pics addObject:coverDic];
                                
                            }

                        }
                }
                   
                    NSDictionary *ebookDic = @{
                                               @"albumId":albumId,
                                               @"pics":pics,
                                               };
                     
                    [self updatePramsparam:ebookDic];
                }
            }];
        }
    }];
}
*/
#pragma mark -电子书操作 1.查询是否生成过电子书 2.修改操作 更新电子书
- (void)queryAlbumEbookAlbumId:(NSNumber *)albumId order:(NSNumber *)order pictures:(NSMutableArray *)pictures updateCover:(BOOL)updateCover{
    
    NSDictionary *row = @{@"page":@(1),@"rows":@(100)};
    
    NSDictionary *dict = @{@"albumId":albumId,
                           @"pageInfo":row,
                           @"order":[order integerValue]==1?@"desc":@"asc",
                           };
    //查询是否有电子书
    [PPNetworkService gettemplateEbookListWithparams:dict callback:^(id data, NSError *error) {
        
        if ([data[@"total"] integerValue] > 0) {
            NSDictionary *ebookDic = @{
                                       @"albumId":albumId,
                                       @"pics":pictures,
                                       };
            
            
            //封面是同一个就不更新电子书，这里描述更新都走的这里 只能依据这个来做判断条件
            
            BOOL isUd = YES;
            if (updateCover && pictures.count==1) {
                NSDictionary *dict = pictures.lastObject;
                if ([data[@"common"][@"pictureId"] integerValue] == [dict[@"pictureId"] integerValue]) {
                    isUd = NO;
                }
            }
            
            if (isUd) {
                [self updatePramsparam:ebookDic];
                PPLog(@"更新电子书！！！！！！！！");
            }
        }else{
            PPLog(@"没有生成过电子书！！！！！！！！");
            
        }
    }];

}
- (void)updatePramsparam:(NSDictionary *)dict{

    //更新电子书

    [PPNetworkService updateAlbumeBookWithParams:dict callback:^(id data, NSError *error) {
        
    }];
    
}
- (PPHomeAlbumModel *)getAlbumInfo:(PPAlbumModel *)album{
    
    PPHomeAlbumModel *albumModel = [[PPHomeAlbumModel alloc] init];
    albumModel.auuid = album.auuid;
    albumModel.albumID = album.albumID;
    albumModel.coverURL = [NSString stringWithFormat:@"%@%@",album.coverHost,album.coverKey];
    albumModel.coverHost = album.coverHost;
    albumModel.coverKey = album.coverKey;
    albumModel.order = [album.order integerValue];
    albumModel.title = album.title;
    albumModel.albumDesc = album.desc;
    albumModel.permission = album.permission;
    albumModel.publish = album.publish;
    albumModel.update = album.update;
    albumModel.privacy = album.privacy;
    albumModel.privacyUserIDs = album.privacyUserIDs;
    
    NSArray <PPAlbumImageModel *> *images = [PPAlbumImageModel where:@{@"auuid" : album.auuid, @"deleted" : @(NO)}];
    NSArray *sortedImages = nil;
    if(album.order.integerValue == PPAlbumOrderDesc) {
        sortedImages = images;
    } else {
        sortedImages = [images.reverseObjectEnumerator allObjects];
    }
    
    albumModel.pictures = [NSMutableArray array];
    [sortedImages enumerateObjectsUsingBlock:^(PPAlbumImageModel *_Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) {
        PPPictureModel *picModel = [[PPPictureModel alloc] init];
        picModel.picID = obj.imageID;
        picModel.picAuuid = obj.auuid;
        picModel.picKey = obj.key;
        picModel.picHost = obj.host;
        picModel.picDesc = obj.desc;
        picModel.picComment = obj.comment;
        picModel.picLike = obj.like;
        picModel.picURL = [NSString stringWithFormat:@"%@%@",obj.host,obj.key];
        picModel.picType = 2;
        [albumModel.pictures addObject:picModel];
        
        if ([obj.key isEqualToString:albumModel.coverKey]) {
            picModel.picType = 1;
            [albumModel.pictures insertObject:picModel atIndex:0];
        }
        
    }];
    return albumModel;
}
- (void)commitOfflineAlbumWithAlbumUUID:(NSString *)auuid completion:(void (^)(void))completion {

    if(auuid == nil) {
        !completion ? : completion();

        return;
    }

    PPAlbumModel *album = [PPAlbumModel find:@{@"auuid" : auuid}];

    if(album == nil) {
        !completion ? : completion();

        return;
    }

    if(album.deleted.boolValue) {
        [self commitOfflineDeletedAlbumWithAlbumUUID:auuid completion:completion];
    } else if(album.created.boolValue) {
        [self commitOfflineCreatedAlbumWithAlbumUUID:auuid completion:completion];
    } else {
        [self commitOfflineModifiedAlbumWithAlbumUUID:auuid completion:completion];
    }
}


- (void)didCreateAlbumWithAlbumUUID:(NSString *)auuid results:(NSDictionary *)results error:(NSError *)error uuidMap:(NSDictionary *)uuidMap completion:(void (^)(void))completion {

    if(error != nil) {
        !completion ? : completion();

        return;
    }

    PPAlbumModel *album = [PPAlbumModel find:@{@"auuid" : auuid}];

    if(album == nil) {
        !completion ? : completion();
    } else {
        [[PPAlbumImageModel where:@{@"auuid" : album.auuid}] enumerateObjectsUsingBlock:^(PPAlbumImageModel *_Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) {
            obj.auuid = auuid;
        }];

        [[PPAlbumTagModel where:@{@"auuid" : album.auuid}] enumerateObjectsUsingBlock:^(PPAlbumTagModel *_Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) {
            obj.auuid = auuid;
        }];

        NSNumber *albumID = [results validNumberForKey:@"albumid"];

        album.albumID = albumID;
        album.created = @(NO);

        [[NSManagedObjectContext threadObjectContext] saveContext];

        if(album.deleted.boolValue) {
            [self commitOfflineAlbumWithAlbumUUID:auuid completion:completion];
        } else {
            dispatch_group_t group = dispatch_group_create();
            for(NSDictionary *picture in [results validArrayForKey:@"pictures"]) {
                NSString *identifier = [picture validStringForKey:@"filename"];
                NSString *key = [picture validStringForKey:@"key"];
                NSString *token = [picture validStringForKey:@"uploadToken"];
                NSString *host = [picture validStringForKey:@"host"];
                dispatch_group_enter(group);

                [[PPImageTransaction sharedInstance] beginTransactionWithAlbumID:album.albumID.integerValue identifier:identifier key:key token:token completion:^(PPAlbumImageID imageID, NSError *error) {
                    NSString *uuid = [uuidMap validStringForKey:identifier];
                    
                    [self didCreatePictureWithUUID:uuid imageID:@(imageID) key:key host:host pictureId:[picture validNumberForKey:@"id"] error:error completion:^{
                        dispatch_group_leave(group);
                    }];
                }];
            }

            dispatch_group_notify(group, dispatch_get_main_queue(), ^{
                [PPNetworkService createAlbumFinishWithAlbumID:albumID callback:^(id data, NSError *error) {
                    [self commitOfflineAlbumWithAlbumUUID:auuid completion:completion];
                }];
            });
        }
    }
}

- (void)didAddPicturesToAlbumWithAlbumID:(NSNumber *)albumID auuid:(NSString *)auuid results:(NSDictionary *)results error:(NSError *)error uuidMap:(NSDictionary *)uuidMap completion:(void (^)(void))completion {
    if(error != nil) {
        !completion ? : completion();

        return;
    }
PPAlbumModel *album = [PPAlbumModel find:@{@"auuid" : auuid}];
    NSMutableArray *pictureIDs = [NSMutableArray array];
    
     NSMutableArray *addPictures = [NSMutableArray array];
    dispatch_group_t group = dispatch_group_create();

    for(NSDictionary *picture in [results validArrayForKey:@"pictures"]) {
        NSString *identifier = [picture validStringForKey:@"filename"];
        NSString *key = [picture validStringForKey:@"key"];
        NSString *token = [picture validStringForKey:@"uploadToken"];
        NSString *host = [picture validStringForKey:@"host"];

        [pictureIDs addSafeObject:[picture validNumberForKey:@"id"]];
        
        
        NSDictionary *addDic = @{
                                 @"pictureId":[picture validNumberForKey:@"id"],
                                 @"url":key,
                                 @"picType":@(2),
                                 @"operateType":@(1),
                                 };
        [addPictures addObject:addDic];
        
        dispatch_group_enter(group);

        [[PPImageTransaction sharedInstance] beginTransactionWithAlbumID:albumID.integerValue identifier:identifier key:key token:token completion:^(PPAlbumImageID imageID, NSError *error) {
            NSString *uuid = [uuidMap validStringForKey:identifier];

            [self didCreatePictureWithUUID:uuid imageID:@(imageID) key:key host:host pictureId:[picture validNumberForKey:@"id"]  error:error completion:^{
                dispatch_group_leave(group);
            }];
        }];
    }

    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        [PPNetworkService finishUploadingPicturesWithPictureIDs:pictureIDs albumID:albumID callback:^(id data, NSError *error) {
           
            [self queryAlbumEbookAlbumId:albumID order:album.order pictures:addPictures updateCover:NO];
            
            !completion ? : completion();
            
//            [self updateAlbumeBookID:albumID cover:nil deletePictures:nil addPictures:pictureIDs order:album.order];
            
            
            
        }];
    });
}

- (void)didCreatePictureWithUUID:(NSString *)uuid imageID:(NSNumber *)imageID key:(NSString *)key host:(NSString *)host pictureId:(NSNumber *)pictureId error:(NSError *)error completion:(void (^)(void))completion {
    if(error != nil || imageID == 0) {
        !completion ? : completion();

        return;
    }

    PPAlbumImageModel *image = [PPAlbumImageModel find:@{@"uuid" : uuid}];

    if(image == nil) {
        !completion ? : completion();
    } else {
        image.imageID = imageID;
        image.key = key;
        image.host = host;
        image.created = @(NO);
        image.pictureId = pictureId;
        if(image.isCover.boolValue) {
            image.isCover = @(NO);

            PPAlbumModel *album = [PPAlbumModel find:@{@"auuid" : image.auuid}];
            album.coverKey = key;
            album.coverHost = host;
            album.modified = @(YES);
        }

        [image.managedObjectContext saveContext];

        if(image.deleted.boolValue) {
            [self commitOfflineAlbumWithAlbumUUID:image.auuid completion:completion];
        } else {
            !completion ? : completion();
        }
    }
}

#pragma mark - Fetch

- (void)synchronizeRemoteAlbumsWithCompletion:(void (^)(NSError *error))completion {

    PPAlbumFetcher *fetcher = [[PPAlbumFetcher alloc] init];

    [fetcher fetchAllAlbumsWithCompletion:^(NSArray *results, NSError *error) {

        if(error == nil) {

            dispatch_async(dispatch_get_global_queue(0, 0), ^{

                NSMutableArray *localAlbumIDs = [NSMutableArray array];
                NSMutableArray *remoteAlbumIDs = [NSMutableArray array];

                NSMutableArray *insertedAlbumIDs = [NSMutableArray array];
                NSMutableArray *deletedAlbumIDs = [NSMutableArray array];
                NSMutableArray *modifiedAlbumIDs = [NSMutableArray array];

                for(NSDictionary *result in results) {
                    [remoteAlbumIDs addSafeObject:[result validNumberForKey:@"albumid"]];
                }

                NSArray <PPAlbumModel *> *localAlbums = [PPAlbumModel where:@{@"deleted" : @(NO)}];

                for(PPAlbumModel *localAlbum in localAlbums) {
                    if(!localAlbum.created.boolValue) {
                        [localAlbumIDs addSafeObject:localAlbum.albumID];
                    }
                }

                for(NSNumber *remoteAlbumID in remoteAlbumIDs) {
                    BOOL exists = NO;

                    for(NSNumber *localAlbumID in localAlbumIDs) {
                        if(localAlbumID.integerValue == remoteAlbumID.integerValue) {
                            exists = YES;
                            break;
                        }
                    }

                    if(!exists) {
                        [insertedAlbumIDs addSafeObject:remoteAlbumID];
                    }
                }

                for(NSNumber *localAlbumID in localAlbumIDs) {
                    BOOL exists = NO;

                    for(NSNumber *remoteAlbumID in remoteAlbumIDs) {
                        if(remoteAlbumID.integerValue == localAlbumID.integerValue) {
                            exists = YES;
                            break;
                        }
                    }

                    if(!exists) {
                        [deletedAlbumIDs addSafeObject:localAlbumID];
                    } else {
                        [modifiedAlbumIDs addSafeObject:localAlbumID];
                    }
                }

                __block NSError *error_ = nil;

                dispatch_group_t group = dispatch_group_create();

                NSArray *updatedAlbumIDs = [insertedAlbumIDs arrayByAddingObjectsFromArray:modifiedAlbumIDs];

                dispatch_apply(updatedAlbumIDs.count, dispatch_get_global_queue(0, 0), ^(size_t idx) {
                    PPAlbumID albumID = [[updatedAlbumIDs safeObjectAtIndex:idx] integerValue];

                    dispatch_group_enter(group);
                    [self mergeAlbumContentsWithAlbumID:albumID completion:^(NSError *error){
                        if(error != nil) {
                            error_ = error;
                        }

                        dispatch_group_leave(group);
                    }];
                });

                for(NSNumber *albumID in deletedAlbumIDs) {
                    PPAlbumModel *album = [PPAlbumModel find:@{@"albumID" : albumID}];
                    [album delete];
                }

                [[NSManagedObjectContext threadObjectContext] saveContext];

                dispatch_group_notify(group, dispatch_get_main_queue(), ^{
                    [[NSNotificationCenter defaultCenter] postNotificationName:PPAlbumManagerDidChangeLocalAlbumsNotification object:nil];

                    !completion ? : completion(error_);
                });

            });

        } else {
            [MobClick event:@"1002" attributes:@{@"error": error}];

            !completion ? : completion(error);
        }
    }];

}

- (void)mergeAlbumContentsWithAlbumID:(PPAlbumID)albumID completion:(void (^)(NSError *))completion {

    [PPNetworkService getAlbumDetailsByAlbumID:@(albumID) callback:^(id data, NSError *error) {

        if(error == nil) {

            dispatch_async(dispatch_get_global_queue(0, 0), ^{

                PPAlbumModel *album = [PPAlbumModel find:@{@"albumID" : @(albumID)}];

                if(album == nil) {
                    album = [PPAlbumModel existingAlbumForUUID:[NSString uuid]];
                }

                album.albumID = @(albumID);
                album.permission = [data validNumberForKey:@"comment"];
                album.coverKey = [data validStringForKey:@"coverImg"];
                album.coverHost = [data validStringForKey:@"coverImgHost"];
                album.publish = @([data validNumberForKey:@"createTime"].doubleValue/1000.0);
                album.update = @([data validNumberForKey:@"modifyTime"].doubleValue/1000.0);
                album.title = [data validStringForKey:@"title"];
                album.desc = [data validStringForKey:@"description"];
                album.order = [data validNumberForKey:@"order"];
                album.privacy = [data validNumberForKey:@"privacy"];
                album.privacyUserIDs = [[data validArrayForKey:@"privacySetting"] componentsJoinedByString:@","];

                NSArray *pictures = [data validArrayForKey:@"pictures"];
                NSArray *sortedPictures = [pictures sortedArrayUsingComparator:^NSComparisonResult (id _Nonnull obj1, id _Nonnull obj2) {
                    NSNumber *imageID1 = [obj1 validNumberForKey:@"pictureid"];
                    NSNumber *imageID2 = [obj2 validNumberForKey:@"pictureid"];

                    return [imageID1 compare:imageID2];
                }];

                for(NSDictionary *picture in sortedPictures) {
                    NSNumber *imageID = [picture validNumberForKey:@"pictureid"];

                    PPAlbumImageModel *image = [PPAlbumImageModel find:@{@"imageID" : imageID}];

                    if(image == nil) {
                        image = [PPAlbumImageModel existingAlbumImageForUUID:[NSString uuid]];
                    }

                    image.imageID = imageID;
                    image.auuid = album.auuid;
                    image.key = [picture validStringForKey:@"key"];
                    image.host = [picture validStringForKey:@"host"];
                    image.desc = [picture validStringForKey:@"description"];
                    image.comment = [picture validNumberForKey:@"comment"];
                    image.like = [picture validNumberForKey:@"like"];
                }

                for(NSDictionary *tagg in [data validArrayForKey:@"tags"]) {
                    NSNumber *tagID = [tagg validNumberForKey:@"tagid"];

                    PPAlbumTagModel *tag = [PPAlbumTagModel existingAlbumTagForTagID:tagID.integerValue];
                    tag.name = [tagg validStringForKey:@"name"];
                    tag.auuid = album.auuid;
                }

                [[NSManagedObjectContext threadObjectContext] saveContext];

                dispatch_async(dispatch_get_main_queue(), ^{
                    !completion ? : completion(error);
                });
            });
        } else {
            !completion ? : completion(error);
        }
    }];

}


// 生成对应的七牛路径成功后 调用此方法上传图片
- (void)uploadEbookPicResults:(NSMutableArray <PPUploaderFile*>*)results completion:(void (^)(NSError *))completion{

    dispatch_group_t group = dispatch_group_create();
    
    for(PPUploaderFile *picture in results) {
        dispatch_group_enter(group);
        
        [[PPImageTransaction sharedInstance] beginTransactionWithupImage:picture.image key:picture.path token:picture.uploadToken completion:^(NSError *error) {
            dispatch_group_leave(group);
        }];
        
    }
    
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
//        [PPNetworkService finishUploadingPicturesWithPictureIDs:pictureIDs albumID:albumID callback:^(id data, NSError *error) {
            !completion ? : completion(nil);
//        }];
        
    });
}
@end
